package com.zdkj.subway.st.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdkj.admin.api.entity.SysDictItem;
import com.zdkj.common.core.constant.SecurityConstants;
import com.zdkj.common.core.exceltools.MultipartFileToFile;
import com.zdkj.common.core.util.R;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.st.dto.in.EsStation;
import com.zdkj.subway.st.entity.SwParamLine;
import com.zdkj.subway.st.entity.SwParamStation;
import com.zdkj.subway.st.entity.SwStPlanDay;
import com.zdkj.subway.st.entity.SwTkOfficialProduction;
import com.zdkj.subway.st.fegin.SubwaySupportService;
import com.zdkj.subway.st.mapper.SwParamLineMapper;
import com.zdkj.subway.st.mapper.SwParamStationMapper;
import com.zdkj.subway.st.mapper.SwTkOfficialTicketMapper;
import com.zdkj.subway.st.service.SwStPlanDayService;
import com.zdkj.subway.st.service.SwTkOfficialProductionService;
import com.zdkj.subway.st.util.DateUtilsSt;
import com.zdkj.subway.st.util.GenSerialNo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 公务票生产
 *
 * @author chenbo
 * @date 2020-06-10 10:21:03
 */
@RestController
@AllArgsConstructor
@RequestMapping("/swtkofficialproduction")
@Api(value = "swtkofficialproduction", tags = "公务票生产管理")
public class SwTkOfficialProductionController {
    private static final Logger LOGGER =
            LoggerFactory.getLogger(SwTkOfficialProduction.class);
    private static final String APPLY_STATUS_NOSUBMIT = "0";
    private static final String APPLY_STATUS_SUBMIT = "1";
    private final SwTkOfficialProductionService swTkOfficialProductionService;
    private final SwStPlanDayService swStPlanDayService;
    private final SwTkOfficialTicketMapper swTkOfficialTicketMapper;
	@Autowired
    private GenSerialNo genSerialNo;
    @Resource
    private SwParamLineMapper swParamLineMapper;
    @Resource
    private SwParamStationMapper swParamStationMapper;
    @Resource
    private SubwaySupportService subwaySupportService;
    /**
     * 分页查询
     *
     * @param page                   分页对象
     * @param swTkOfficialProduction 公务票生产
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page")
    public R getSwTkOfficialProductionPage(Page page, SwTkOfficialProduction swTkOfficialProduction, String roleSH) {
        LambdaQueryWrapper<SwTkOfficialProduction> queryWrapper = Wrappers.query(swTkOfficialProduction).orderByDesc("apply_time").lambda();
        List<String> dateConditionsq = swTkOfficialProduction.getDates1();
        if (ObjectUtil.isNotEmpty(dateConditionsq)) {
            //queryWrapper.between(SwTkOfficialProduction::getApplyTime, dateConditionsq.get(0), dateConditionsq.get(1));
            queryWrapper.apply("DATE_FORMAT(APPLY_TIME,'%Y-%m-%d') between DATE_FORMAT('"+dateConditionsq.get(0)+"','%Y-%m-%d') and DATE_FORMAT('"+dateConditionsq.get(1)+"','%Y-%m-%d')");
        }
//        if (roleSH != null) {
//            return R.ok(swTkOfficialProductionService.page(page, queryWrapper
//                    .eq(SwTkOfficialProduction::getApplyStatus, roleSH)));
//        }
        return R.ok(swTkOfficialProductionService.page(page, queryWrapper
        ));
    }

    /**
     * 批量提交公务票生产
     *
     * @param list 公务票生产
     * @return R
     */
    @ApiOperation(value = "批量提交公务票生产", notes = "批量提交公务票生产")
    @SysLog("批量提交公务票生产")
    @PutMapping("submitBatch")
    @PreAuthorize("@pms.hasPermission('st_swtkofficialproduction_submitBatch')")
    public R submitBatch(@RequestBody List<SwTkOfficialProduction> list) {
        for (SwTkOfficialProduction swTkOfficialProduction : list) {
            if (swTkOfficialProduction.getApplyStatus().equals(APPLY_STATUS_NOSUBMIT)) {
                //swTkOfficialProduction.setApplyTime(LocalDateTime.now());
                swTkOfficialProduction.setApplyStatus(APPLY_STATUS_SUBMIT);
            } else {
                break;
            }
        }
        return R.ok(swTkOfficialProductionService.updateBatchById(list));
    }

    /**
     * 导出
     *
     * @param page                   分页对象
     * @param swTkOfficialProduction 公务票信息
     * @return
     */
//    @ApiOperation(value = "公务票信息导出", notes = "公务票信息导出")
//    @GetMapping("/export")
//    //TODO 待确定状态字段
//    @PreAuthorize("@pms.hasPermission('st_swtkofficialticket_export')")
//    public void getSwStInvoiceBalanceExport(Page page, SwTkOfficialProduction swTkOfficialProduction, HttpServletResponse response) throws IOException {
//        Page a = swTkOfficialProductionService.pageExport(page, new CustomQueryWrapper(SwTkOfficialProduction.class)
//                .addDTO(swTkOfficialProduction)
//                .addAlis("a")
//                .addDelFlag(Boolean.TRUE)
//                .init());
//        // 写法1
//        String fileName = URLEncoder.encode("公务票生产", "UTF-8");
//        //"C:\\Users\\Administrator\\Desktop\\" + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
//        // 这里 需要指定写用哪个class去写，然后写到第一个sheet，名字为模板 然后文件流会自动关闭
//        // 如果这里想使用03 则 传入excelType参数即可
//        response.setHeader("Content-disposition", "attachment;filename=" + fileName + DateUtilsSt.getDatetimeNowFormatter() + ".xlsx");
//        EasyExcel.write(response.getOutputStream(), SwTkOfficialProduction.class).registerConverter(new LocalDateTimeConverter())
//                .registerConverter(new LocalDateConverter()).sheet("公务票生产").doWrite(a.getRecords());
//    }


    /**
     * 导出
     * @param
     * @return
     */
    @ApiOperation(value = "导出", notes = "导出")
    @GetMapping({"/export"})
    @SysLog("公务票生产申请导出")
    @PreAuthorize("@pms.hasPermission('st_swtkofficialticket_export')")
    public void export(SwTkOfficialProduction swTkOfficialProduction, HttpServletResponse response) {
        swTkOfficialProductionService.export(swTkOfficialProduction,response);

    }
    /**
     * 批量审批公务票生产
     *
     * @param list 公务票生产
     * @return R
     */
    @ApiOperation(value = "批量审批公务票生产", notes = "批量审批公务票生产")
    @SysLog("批量审批公务票生产")
    @PutMapping("auditBatch")
    @PreAuthorize("@pms.hasPermission('st_swtkofficialproduction_auditBatch')")
    public R auditBatch(@RequestBody List<SwTkOfficialProduction> list) {
        for (SwTkOfficialProduction swTkOfficialProduction : list) {
            swTkOfficialProduction.setAuditTime(LocalDateTime.now());
        }
        boolean b = swTkOfficialProductionService.updateBatchById(list);
        if(b){
            ArrayList<SwStPlanDay> swStPlanDayAList = new ArrayList<>();
            list.forEach(item -> {
                SwTkOfficialProduction swTkOfficialProduction = swTkOfficialProductionService.getById(item);

                if(swTkOfficialProduction.getApplyStatus().equals("2")){
                    SwStPlanDay swStPlanDay = new SwStPlanDay();
                    PigxUser user = SecurityUtils.getUser();
					//单号生成规则
					String generateNum = genSerialNo.generateNum("L2");
                    swStPlanDay.setNumbers(generateNum);
                    swStPlanDay.setWorkTime(String.valueOf(swTkOfficialProduction.getApplyTime().getYear()));//年
                    swStPlanDay.setPlanMonth(String.valueOf(swTkOfficialProduction.getApplyTime().getMonthValue()));//月
                    swStPlanDay.setPlanWeek(DateUtilsSt.whatWeek(DateUtilsSt.StringToLocalDate(swTkOfficialProduction.getApplyTime())));//周
                    swStPlanDay.setTicketType("GWP");//公务票
                    if("0".equals(swTkOfficialProduction.getTicketType())){
                        swStPlanDay.setTicketName("BZK");//本站卡
                    }else if("1".equals(swTkOfficialProduction.getTicketType())){
                        swStPlanDay.setTicketName("LSTQK");//临时通勤卡
                    }else {//3代表员工卡
                        swStPlanDay.setTicketName("YGK");//员工卡
                    }
                    swStPlanDay.setTicketPrice(new BigDecimal(swTkOfficialProduction.getMoney()==null?"0.00":swTkOfficialProduction.getMoney()));
                    swStPlanDay.setTicketTimes(swTkOfficialProduction.getCount());//车票次数
                    swStPlanDay.setTicketNumber(swTkOfficialProduction.getTicketNum());//车票张数
                    swStPlanDay.setActiveTime(swTkOfficialProduction.getValidityTime());//车票有效期
                    swStPlanDay.setPlanFinishTime(swTkOfficialProduction.getApplyTime());//计划完成时间

                    swStPlanDay.setDisplay(true);//审核通过显示
                    swStPlanDay.setPlanType("2");//生产计划类型
                    swStPlanDay.setDataSource("2");//数据来源:0:周计划分解;1:无效票;2:公务票;3:临时计划
                    swStPlanDay.setLatestStartTime(swTkOfficialProduction.getApplyTime());//最晚启用时间
                    //swStPlanDay.setDataSource(swTkOfficialProduction.getDataSource());//数据来源：0车站--1线网
					//任务类型:1:初始化任务、2:票卡初始化任务、3:票卡重编码任务、4:注销任务
					String initWorkType = swTkOfficialProduction.getWorkType();
					if(StringUtils.isNotEmpty(initWorkType)){
                       swStPlanDay.setTaskType(initWorkType);
					}
                    String issuingMethod = swTkOfficialProduction.getIssuingMethod();//发卡方式
                    if(StringUtils.isNotEmpty(issuingMethod)){
                        swStPlanDay.setIssuingMethod(issuingMethod);
                    }
					//增加起始站点和备注信息同步到日计划中  TODO  20220325
					String lineCode=swTkOfficialProduction.getLineCode();
					String stationCode = swTkOfficialProduction.getStationCode();
					String applyCase = swTkOfficialProduction.getApplyCase();
					if(lineCode==null || "".equals(lineCode)){
					    lineCode="0";
						stationCode="";
					}
					//根据线路和车站编号查找对照表数据  
					String esStartStation ="";
					String esEndStation="";
					//调用接口查询	TODO
                    if("2".equals(swTkOfficialProduction.getWorkType()) || "3".equals(swTkOfficialProduction.getWorkType())){
                        EsStation esStation = subwaySupportService.getEsStationInfo(SecurityConstants.FROM_IN, lineCode
                                , stationCode).getData();
                        if(ObjectUtil.isNotEmpty(esStation)){
                            String nameCn = esStation.getNameCn();
                            esStartStation = nameCn;
                            esEndStation = nameCn;
                        }
                    }

                    swStPlanDay.setRemark(applyCase);
					swStPlanDay.setEsStartStation(esStartStation);
					swStPlanDay.setEsEndStation(esEndStation);

                    swStPlanDay.setCheckStatus("0");
                    swStPlanDay.setCreatorName(user.getUsername());
                    swStPlanDay.setCreatorId(user.getId().longValue());
                    swStPlanDayAList.add(swStPlanDay);
                }
              
            });
		   if(swStPlanDayAList.size()>0){
               swStPlanDayService.saveBatch(swStPlanDayAList);
           }

        }
        return R.ok();
    }


    /**
     * 通过id查询公务票生产
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}")
    public R getById(@PathVariable("id") Integer id) {
        return R.ok(swTkOfficialProductionService.getById(id));
    }

    /**
     * 新增公务票生产
     *
     * @param swTkOfficialProduction 公务票生产
     * @return R
     */
    @ApiOperation(value = "新增公务票生产", notes = "新增公务票生产")
    @SysLog("新增公务票生产")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('st_swtkofficialproduction_add')")
    public R save(@RequestBody SwTkOfficialProduction swTkOfficialProduction) {
        SwTkOfficialProduction defaultObj = ObjectUtils.getDefaultObj(SwTkOfficialProduction.class);
        defaultObj.setTicketName("GWP");//公务票
        BeanUtil.copyProperties(swTkOfficialProduction, defaultObj,
                ObjectUtils.getNullAndEmptyPropertyNames(swTkOfficialProduction));
        return R.ok(swTkOfficialProductionService.save(defaultObj));
    }

    /**
     * 修改公务票生产
     *
     * @param swTkOfficialProduction 公务票生产
     * @return R
     */
    @ApiOperation(value = "修改公务票生产", notes = "修改公务票生产")
    @SysLog("修改公务票生产")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('st_swtkofficialproduction_edit')")
    public R updateById(@RequestBody SwTkOfficialProduction swTkOfficialProduction) {
        swTkOfficialProduction.setUpdateTime(LocalDateTime.now());
        return R.ok(swTkOfficialProductionService.updateById(swTkOfficialProduction));
    }


    /**
     * 通过ids删除公务票生产
     *
     * @param ids id
     * @return R
     */
    @ApiOperation(value = "通过ids删除公务票生产", notes = "通过ids删除公务票生产")
    @SysLog("通过ids删除公务票生产")
    @DeleteMapping("/delBatch")
    @PreAuthorize("@pms.hasPermission('st_swtkofficialproduction_delBatch')")
    public R delBatch(@RequestBody List<Integer> ids) {
        return R.ok(swTkOfficialProductionService.removeByIds(ids));
    }

    /**
     * 通过id删除公务票生产
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除公务票生产", notes = "通过id删除公务票生产")
    @SysLog("通过id删除公务票生产")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('st_swtkofficialproduction_del')")
    public R removeById(@PathVariable Integer id) {
        return R.ok(swTkOfficialProductionService.removeById(id));
    }


    @ApiOperation(value = "批量导入公务票生产申请信息", notes = "批量导入公务票生产申请信息")
    @SysLog("批量导入公务票生产申请信息")
    @PostMapping("/saveBatch")
    @PreAuthorize("@pms.hasPermission('st_swtkofficialproduction_import')")
    public R saveBatch(@RequestParam("file") MultipartFile file) throws Exception {
        File excelFile = MultipartFileToFile.multipartFileToFile(file);
        PigxUser user = SecurityUtils.getUser();
        List<SwTkOfficialProduction> objects = new ArrayList<>();
        Map<String, String> officialTypeMaps = new HashMap<>();//票卡类别
        Map<String, String> workTypeMaps = new HashMap<>();//工作类别
        List<SysDictItem> officialTypeList = swTkOfficialTicketMapper.officialTypeMaps();
        for (SysDictItem sysDictItem : officialTypeList) {
            officialTypeMaps.put(sysDictItem.getLabel(),sysDictItem.getValue());
        }
        List<SysDictItem> workTypeList = swTkOfficialTicketMapper.workTypeMaps();
        for (SysDictItem sysDictItem : workTypeList) {
            workTypeMaps.put(sysDictItem.getLabel(),sysDictItem.getValue());
        }
        List<Map<Integer, String>> listMap = EasyExcel.read(excelFile).sheet().headRowNumber(2).doReadSync();
        if (CollectionUtil.isNotEmpty(listMap)) {
            MultipartFileToFile.delteTempFile(excelFile);
            for (int m = 0; m < listMap.size(); m++) {

                Map<Integer, String> data = listMap.get(m);
                // 返回每条数据的键值对 key表示所在的列位置 value表示所在列的值
                LOGGER.info("读取到数据:{}", JSON.toJSONString(data));
                //业务处理
                SwTkOfficialProduction swTkOfficialProduction = new SwTkOfficialProduction();
                //格式进行校验
                R validation = validation(m, data, officialTypeMaps, workTypeMaps);
                if(1 == validation.getCode()){
                    return validation;
                }
                String lineName = data.get(0);
                String stationName = data.get(1);
                if(!"".equals(lineName)){
                    SwParamLine swParamLine = swParamLineMapper.selectOne(Wrappers.<SwParamLine>lambdaQuery().eq(SwParamLine::getName, lineName));
                    if(ObjectUtil.isEmpty(swParamLine)){
                        return R.failed("导入失败，请检查第" + (m+3) +"行【线路】后重新导入！");
                    }
                    swTkOfficialProduction.setLineCode(swParamLine.getCode());//线路
                }
                if(!"".equals(lineName)&&!"".equals(stationName)){
                    SwParamStation swParamStation = swParamStationMapper.selectOne(Wrappers.<SwParamStation>lambdaQuery()
                            .eq(SwParamStation::getLineCode, swTkOfficialProduction.getLineCode()).eq(SwParamStation::getName, stationName));
                    if(ObjectUtil.isEmpty(swParamStation)){
                        return R.failed("导入失败，请检查第" + (m+3) +"行【站点】后重新导入！");
                    }
                    swTkOfficialProduction.setStationCode(swParamStation.getCode());//站点
                }
                swTkOfficialProduction.setTicketType(officialTypeMaps.get(data.get(2)));
                swTkOfficialProduction.setWorkType(workTypeMaps.get(data.get(3)));
                if(StringUtils.isNotEmpty(data.get(4))){
                    swTkOfficialProduction.setIssuingMethod(data.get(4));
                }
                swTkOfficialProduction.setTicketName("GWP");//票卡名称公务票
                swTkOfficialProduction.setApplyType("0");//默认0 临时计划生产
                swTkOfficialProduction.setCount(Integer.parseInt(data.get(5)));
                swTkOfficialProduction.setApplyTime(DateUtilsSt.stringTolocalDateTime(data.get(6)));
                if(StringUtils.isEmpty(data.get(7))){
                    swTkOfficialProduction.setMoney("0");
                }else {
                    swTkOfficialProduction.setMoney(data.get(7));
                }
                swTkOfficialProduction.setValidityTime(data.get(8));
                swTkOfficialProduction.setTicketNum(Integer.parseInt(data.get(9)));
                swTkOfficialProduction.setApplyCase(data.get(10));
                swTkOfficialProduction.setApplyStatus("0");//默认未提交
                swTkOfficialProduction.setDeptId(user.getDeptId());
                swTkOfficialProduction.setCreatorId(user.getId());
                swTkOfficialProduction.setCreatorName(user.getNikeName());
                swTkOfficialProduction.setCreateTime(LocalDateTime.now());
                objects.add(swTkOfficialProduction);
            }
        }
        if (CollectionUtil.isNotEmpty(objects)){
            swTkOfficialProductionService.saveBatch(objects);
        }
        return R.ok();
    }

    /**
     * 格式校验
     * @param m
     * @param data
     * @param officialTypeMaps
     * @param workTypeMaps
     * @return
     */
    public R validation(int m, Map<Integer, String> data, Map<String, String> officialTypeMaps, Map<String, String> workTypeMaps) {
        if(!officialTypeMaps.containsKey(data.get(2))){
            return R.failed("请检查 第" + (m+3) +"行 票卡类别是否正确！");
        }
        if(!workTypeMaps.containsKey(data.get(3))){
            return R.failed("请检查 第" + (m+3) +"行 工作类别是否正确！");
        }
        String format = "yyyy-MM-dd";
        String dateStr = data.get(6);
        if(dateStr.length()>10){
            format = "yyyy-MM-dd HH:mm:ss";
        }
        boolean date = DateUtilsSt.isDate(dateStr, format);//检查日期格式是否正确
        if(!date){
            return R.failed("请检查 第" + (m+3) +"行 申请时间格式是否正确！");
        }
        return R.ok();
    }

}
